package android.life.extensions;

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.component.CompatAbility;
import android.component.CompatSlice;
import android.life.viewmodel.ViewModelProvider;
import android.life.viewmodel.ViewModelStore;
import android.life.viewmodel.ViewModelStoreOwner;
import ohos.aafwk.ability.AbilityPackage;

/**
 * Utilities methods for {@link android.life.viewmodel.ViewModelStore} class.
 */
public class ViewModelProviders {

    /**
     *  This class should not be directly instantiated
     */
    public ViewModelProviders() {
    }

    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given
     * {@code fragment} is alive. More detailed explanation is in {@link android.life.viewmodel.ViewModel}.
     * <p>
     * It uses the {@link CompatSlice#getDefaultViewModelProviderFactory() default factory}
     * to instantiate new ViewModels.
     *
     * @param fragment a fragment, in whose scope ViewModels should be retained
     * @return a ViewModelProvider instance
     * {@link ViewModelProvider#ViewModelProvider(ViewModelStore, ViewModelProvider.Factory)} (ViewModelStoreOwner)},
     * passing in the fragment.
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull CompatSlice fragment) {
        return new ViewModelProvider(fragment);
    }

    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity
     * is alive. More detailed explanation is in {@link android.life.viewmodel.ViewModel}.
     * <p>
     * It uses the {@link CompatSlice#getDefaultViewModelProviderFactory() default factory}
     * to instantiate new ViewModels.
     *
     * @param activity an activity, in whose scope ViewModels should be retained
     * @return a ViewModelProvider instance
     * {@link ViewModelProvider#ViewModelProvider(ViewModelStoreOwner, ViewModelProvider.Factory)} (ViewModelStoreOwner)},
     * passing in the activity.
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull CompatAbility activity) {
        return new ViewModelProvider(activity);
    }

    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given
     * {@code fragment} is alive. More detailed explanation is in {@link android.life.viewmodel.ViewModel}.
     * <p>
     * It uses the given {@link android.life.viewmodel.ViewModelProvider.Factory} to instantiate new ViewModels.
     *
     * @param fragment a fragment, in whose scope ViewModels should be retained
     * @param factory  a {@code Factory} to instantiate new ViewModels
     * @return a ViewModelProvider instance
     * {@link ViewModelProvider#ViewModelProvider(ViewModelStore, ViewModelProvider.Factory)} (ViewModelStoreOwner, Factory)},
     * passing in the fragment and factory.
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull CompatSlice fragment, @Nullable ViewModelProvider.Factory factory) {
        if (factory == null) {
            factory = fragment.getDefaultViewModelProviderFactory();
        }
        return new ViewModelProvider(fragment.getmViewModelStore(), factory);
    }

    /**
     * Creates a {@link ViewModelProvider}, which retains ViewModels while a scope of given Activity
     * is alive. More detailed explanation is in {@link android.life.viewmodel.ViewModel}.
     * <p>
     * It uses the given {@link android.life.viewmodel.ViewModelProvider.Factory} to instantiate new ViewModels.
     *
     * @param activity an activity, in whose scope ViewModels should be retained
     * @param factory  a {@code Factory} to instantiate new ViewModels
     * @return a ViewModelProvider instance
     * {@link ViewModelProvider#ViewModelProvider(ViewModelStore, ViewModelProvider.Factory)} (ViewModelStoreOwner, Factory)}
     * ,
     * passing in the activity and factory.
     */
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull CompatAbility activity,
                                       @Nullable ViewModelProvider.Factory factory) {
        if (factory == null) {
            factory = activity.getDefaultViewModelProviderFactory();
        }
        return new ViewModelProvider(activity.getmViewModelStore(), factory);
    }

    /**
     * {@link android.life.viewmodel.ViewModelProvider.Factory} which may create {@link android.life.viewmodel.OhosViewModel} and
     * {@link android.life.viewmodel.ViewModel}, which have an empty constructor.
     *
     */
    @SuppressWarnings("WeakerAccess")
    public static class DefaultFactory extends ViewModelProvider.OhosViewModelFactory {
        /**
         * Creates a {@code AndroidViewModelFactory}
         *
         * @param application an application to pass in {@link android.life.viewmodel.OhosViewModel}
         * Use {@link ViewModelProvider.OhosViewModelFactory} or
         * {@link ViewModelProvider.OhosViewModelFactory#getInstance(AbilityPackage)} (Application)}.
         */

        public DefaultFactory(@NonNull AbilityPackage application) {
            super(application);
        }
    }
}

